﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCacheData.h
//    @Author           :    Gao.Yi
//    @Date             :    2025-08-11
//    @Email			:    445267987@qq.com
//    @Module           :    NFCacheData
//    @Desc             :    
//
// -------------------------------------------------------------------------

#pragma once

#include "NFComm/NFObjCommon/NFObject.h"
#include "NFServerTypeDefine.h"

/**
 * @def CACHE_DATA_EXPIRE_TIME_SEC
 * @brief 缓存数据的默认续期时间（秒）
 */
#define CACHE_DATA_EXPIRE_TIME_SEC 300
/**
 * @def CACHE_DATA_CREATE_TIMEOUT_SEC
 * @brief 缓存对象自创建起的超时时间（秒），超过该时间视为超时（用于兜底清理）
 */
#define CACHE_DATA_CREATE_TIMEOUT_SEC 300

/**
 * @def CACHE_DATA_MIN_SCAN_NUM
 * @brief 触发负载扫描时，最小扫描数量（避免小池扫描过少导致清理不充分）
 */
#define CACHE_DATA_MIN_SCAN_NUM 100
/**
 * @def CACHE_DATA_LOAD_FACTOR
 * @brief 负载触发阈值系数，已用数量超过 itemCount*该系数 时触发淘汰扫描
 */
#define CACHE_DATA_LOAD_FACTOR (0.5f)
/**
 * @def CACHE_DATA_SCAN_FACTOR
 * @brief 本次扫描数量占对象池容量的比例（与最小扫描数量取较大者）
 */
#define CACHE_DATA_SCAN_FACTOR (0.1f)

/**
 * @class NFCacheData
 * @brief 缓存数据基类（共享内存对象）
 *
 * 提供统一的缓存生命周期管理：
 * - 通过 `SetExpireTime()` 实现滑动过期（访问续期）
 * - 通过 `IsTimeOut()` 实现创建兜底超时判断
 * - 统一的对象标识 `m_ullId` 与时间戳维护
 *
 * 继承者需要实现：
 * - `InitData(const google::protobuf::Message*)` 用于从 PB 初始化数据
 *
 * 约束与约定：
 * - 本类应由共享内存对象管理器创建与回收
 * - 时间相关接口使用 `NF_ADJUST_TIMENOW()` 获取统一时间源
 */
class NFCacheData : public NF_OBJECT_TEMPLATE_MACRO(NFCacheData, EOT_CACHE_DATA_OBJ, NFObject)
public:
    /**
     * @brief 构造函数，根据共享内存创建模式调用 CreateInit/ResumeInit
     */
    NFCacheData();
    /**
     * @brief 析构函数
     */
    ~NFCacheData() override;
    /**
     * @brief 首次创建初始化（共享内存冷启动场景）
     * @return 0表示成功，其他为错误码
     */
    int CreateInit();
    /**
     * @brief 进程重启后恢复初始化（共享内存热启动场景）
     * @return 0表示成功，其他为错误码
     */
    int ResumeInit();

public:
    /**
     * @brief 从 Protobuf 消息初始化数据
     *
     * 该方法用于从给定的 Protobuf 消息对象中初始化缓存数据。
     * 子类可以重写此方法以实现具体的初始化逻辑。
     *
     * @param pMessage 指向 Protobuf 消息对象的指针
     * @return 0 表示成功，其他值为错误码
     */
    virtual int InitDataFromMessage(const google::protobuf::Message* pMessage) { return 0; }

    /**
     * @brief 初始化配置
     *
     * 该方法用于初始化缓存数据的配置信息。
     * 子类可以重写此方法以实现具体的配置初始化逻辑。
     *
     * @return 0 表示成功，其他值为错误码
     */
    virtual int InitConfig() { return 0; }

    /**
     * @brief 获取对象ID
     *
     * 该方法用于获取当前缓存对象的唯一标识ID。
     *
     * @return 返回对象ID，默认值为0
     */
    virtual uint64_t GetCacheId() const { return 0; }

public:
    /** @return 当前对象的过期时间戳（秒） */
    virtual uint32_t GetCacheExpireTime() const { return m_dwCacheExpireTime; }
    /** @return 当前对象的创建时间戳（秒） */
    virtual uint32_t GetCacheCreateTime() const { return m_dwCacheCreateTime; }

public:
    /**
     * @brief 将过期时间续期至 当前时间 + GetExpireTimeSec()
     * @return 0表示成功
     */
    virtual int SetCacheExpireTime();
    /**
     * @brief 是否已达到创建兜底超时（与访问续期无关）
     * @return true为已超时，需要业务侧考虑淘汰；false为未超时
     */
    virtual bool IsCacheTimeOut() const;

public:
    /** @return 创建兜底超时秒数，默认 `CACHE_DATA_CREATE_TIMEOUT_SEC` */
    virtual int GetCacheCreateTimeoutSec() const { return CACHE_DATA_CREATE_TIMEOUT_SEC; }
    /** @return 单次访问续期期限秒数，默认 `CACHE_DATA_EXPIRE_TIME_SEC` */
    virtual int GetCacheExpireTimeSec() const { return CACHE_DATA_EXPIRE_TIME_SEC; }

protected:
    /** @brief 过期时间戳（秒），用于滑动过期判断 */
    uint32_t m_dwCacheExpireTime;
    /** @brief 创建时间戳（秒），用于创建兜底超时判断 */
    uint32_t m_dwCacheCreateTime;
};
